package com.shakespace.artofandroid.chapter13other

import android.content.Context
import android.content.pm.PackageManager
import android.os.Build
import android.os.Environment
import java.io.*
import java.lang.Exception
import java.text.SimpleDateFormat

/**
 * created by  shakespace
 * 2021/4/14  10:08
 */
@Suppress("DEPRECATION")
class CrashHandler private constructor() : Thread.UncaughtExceptionHandler {
    lateinit var context: Context
    private val crashHandler: Thread.UncaughtExceptionHandler? = Thread.getDefaultUncaughtExceptionHandler()

    /**
     * 1. 需要添加读写权限， 并主动申请
     */
    private val Path = Environment.getExternalStorageDirectory().path + "/CrashTest/log"
    init {
        Thread.setDefaultUncaughtExceptionHandler(this)
    }

    fun create(ctx: Context) {
        context = ctx.applicationContext
    }

    /**
     * 处理未捕获的异常
     */
    override fun uncaughtException(t: Thread, e: Throwable) {
        try {
            dumpExceptionToSDCard(e)
            // optional  上传到服务器
        } catch (e: Exception) {
            e.printStackTrace()
        }
        // 如果有默认的处理，使用默认的处理
        crashHandler?.uncaughtException(t, e)
        //
//        Process.killProcess(Process.myPid())
    }

    @Throws(IOException::class)
    fun dumpExceptionToSDCard(t: Throwable) {
        val dir = File(Path)
        if (!dir.exists()) {
            dir.mkdirs()
        }
        val current = System.currentTimeMillis()
        val dateTime = SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(current)

        val file = File(Path + FILE_NAME + dateTime + FILE_NAME_SUFFIX)

        try {
            // 创建输出流用于写入
            val pw = PrintWriter(BufferedWriter(FileWriter(file)))
            pw.println(dateTime)
            dumpPhoneInfo(pw)
            pw.println()
            t.printStackTrace(pw)
            pw.close()
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }

    @Throws(PackageManager.NameNotFoundException::class)
    fun dumpPhoneInfo(pw: PrintWriter) {
        val packageInfo = context.packageManager.getPackageInfo(
            context.packageName,
            PackageManager.GET_ACTIVITIES
        )
        pw.println("AppVersion : ${packageInfo.versionName}_${packageInfo.versionCode}")
        pw.println("OSVersion : ${Build.VERSION.RELEASE}_${Build.VERSION.SDK_INT}")
        pw.println("Vendor : ${Build.MANUFACTURER}")
        pw.println("Model : ${Build.MODEL}")
        pw.println("CPU ABI  : ${Build.CPU_ABI}")
    }


    companion object {
        const val DEBUG = true

        const val FILE_NAME = "crash"
        const val FILE_NAME_SUFFIX = ".trace"

        val handler = CrashHandler()
        fun getInstance(): CrashHandler {
            return handler
        }
    }
}